/*********************************** (C) COPYRIGHT ******************************
 * address: https://gitee.com/liuniansihuo/multitasks-os
 *
 * Change Logs:
 * Date			Author      	Notes
 * 2019-06-26	LiuHuo			first version
 *
 * Modify Note:By default, zhe system tick is 1ms ,Don't consider Time overflows For the time being,
 *  2^32 ms = 1193.046h = 49.7 day . when app continue working more than 49.7 days,that must be consider
*******************************************************************************/

#define __os_tick_C_
#include "cpu.h"
#include "typedef.h"
#include "os_tick.h"
#include "sys_config.h"
#if SYS_COMPENT_TICK_WORK
#include "tick_work.h"
#endif



static SysTick_t sys_tick_curr=0;
static RCC_ClocksTypeDef RCCSysClocks;
static SysTick_t sys_stimestamp_sec=1735660800 + 8*3600;//2025-01-01 00:00:00 + NTC 8 hours
static u32  sys_stimestamp_msec=0;


static void os_delay_init(void);




u32 system_clock_fre_get(u8 type)
{
	u32 clock=0;
	switch(type)
	{
		case SYSCLK_FRE:
			clock = RCCSysClocks.SYSCLK_Frequency;
			break;
		case HCLK_FRE:
			clock = RCCSysClocks.HCLK_Frequency;
			break;
		case PCLK1_FRE:
			clock = RCCSysClocks.PCLK1_Frequency;
			break;
		case PCLK2_FRE:
			clock = RCCSysClocks.PCLK2_Frequency;
			break;
		case ADCCLK_FRE:
			clock = RCCSysClocks.ADCCLK_Frequency;
			break;
	}
	return clock;
}

void systick_compensation(u32 time)
{
	sys_tick_curr += time;
}

void SysTick_Handler(void)
{
	sys_tick_curr++;
#if SYS_TIMESTAMP
	sys_stimestamp_msec=sys_tick_curr%1000;
	if(0 == sys_tick_curr%1000)
		sys_stimestamp_sec++;
#endif
    #if SYS_COMPENT_TICK_WORK
    work_tick_process();
    #endif
}

void systick_init(void)
{

	RCC_GetClocksFreq(&RCCSysClocks);

	u32 SysCLckPerS = RCCSysClocks.HCLK_Frequency/1000;

	if(1 == SysTick_Config(SysCLckPerS))
		while(1);

	os_delay_init();
}
/*
* function:当前系统时间，所有应用的调用都应该基于该定义，考虑可移植??
* param:
* return:系统时间
*/
SysTick_t systick_get_currTime(void)
{
	return sys_tick_curr;
}
/*
* function:获取与当前系统时间的??
* param:要比较的时间，改时间必须要小于系统时??
* return:返回与系统时间差
*/
u32 systick_get_time_difference(SysTick_t Time)
{
	return (sys_tick_curr-Time);
}
/*
* function：比较与当前系统时间的时间差是否OK,成功并赋值当前系统时??
* param:
	Time:比较时间的地址
	diff:比较差??
* return:
	1:时间差已OK
	0:no OK
*/
u8 systick_get_difference_assign(SysTick_t *Time,u32 diff)
{
	SysTick_t Ms=sys_tick_curr;
	if((Ms-*Time)>=diff)
	{
		*Time = Ms;
		return 1;
	}
	else
		return 0;
}
SysTick_t sys_timestamp_get(void)
{
	return sys_stimestamp_sec;
}
void sys_timestamp_set(SysTick_t T)
{
	sys_stimestamp_sec = T;
}
SysTick_t sys_timestamp_msec_get(void)
{
	return sys_stimestamp_msec;
}
/*******************************************************************************
************************************延时定义*************************************
*******************************************************************************/


#define HARD_TIM_ENABLE	0


#define DELAY_TIMx		TIM6
#define DELAY_RCC		RCC_APB1Periph_TIM6
/*
注意：时钟参数要根据所用MCU和PLK时钟进行调整
((1+TIM_Prescaler )/40M)*(1+TIM_Period )
*/
static void os_delay_init(void)
{
#if HARD_TIM_ENABLE
	/*开启TIM时钟*/
	RCC_APB1PeriphClockCmd(DELAY_RCC,ENABLE);			//初始化TIM时钟

	TIM_SelectOnePulseMode(DELAY_TIMx, TIM_OPMode_Single);//在发生下一次更新事件(清除 CEN 位)时，计数器停止
	TIM_ARRPreloadConfig(DELAY_TIMx, DISABLE);
	TIM_UpdateRequestConfig(DELAY_TIMx, TIM_UpdateSource_Global);
	TIM_SetAutoreload(DELAY_TIMx, 1);
	TIM_PrescalerConfig(DELAY_TIMx, 144-1, TIM_PSCReloadMode_Immediate);

	TIM_Cmd(DELAY_TIMx, DISABLE);
#endif
}

void delay_us(u32 us)
{
#if HARD_TIM_ENABLE
	DELAY_TIMx->ATRLR = us;//TIM_SetAutoreload(DELAY_TIMx, us);
	DELAY_TIMx->CTLR1 |= TIM_CEN;//TIM_Cmd(DELAY_TIMx, ENABLE);
	while( DELAY_TIMx->CTLR1&TIM_CEN );
#else

	unsigned int cnt;
	while(us)
	{
		cnt=26;//不同的系统时钟或mcu要调整校准这个值
		while(cnt)
			cnt--;
		us--;
	}
#endif
}

void delay_ms(u32 ms)
{
    #if 0
	while(ms)
	{
		delay_us(1000);
		ms--;
	}
    #else
    SysTick_t Ms=sys_tick_curr;
    while((sys_tick_curr-Ms)<ms);
    #endif
}

